home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_10 / 9n10058a < prev    next >
Text File  |  1991-01-21  |  6KB  |  185 lines

  1. /*  memdebug.c  source file for debugging versions of malloc, 
  2.     calloc, realloc and free.  Copywrite 1990 by Wahhab 
  3.     Baldwin.  Permission to copy freely granted if this 
  4.     notice is included.
  5. */
  6.  
  7. #include <malloc.h>
  8. #include <string.h>
  9.  
  10. #if defined(DEBUG)
  11.     #undef DEBUG
  12. #endif
  13. #include "memdebug.h"
  14.  
  15. #define MAXMODS 100
  16. #define SENTINAL_INT  0xEEEE
  17.  
  18. void d__add_to_ll(PMEMCHAIN mptr, size_t bytes, 
  19.                     char *module, int line);
  20. void d__fatal(char *msg, int value, char *module, int line);
  21.  
  22. char modlist[MAXMODS][11];
  23. PMEMCHAIN memchainhead;
  24.  
  25. void *d__malloc(size_t bytes, char *module, int line)
  26. {
  27.     PMEMCHAIN mptr;
  28.  
  29.     if (bytes < 1)
  30.         d__fatal("Called malloc() with < 1 bytes:", 
  31.                     bytes, module, line);
  32.     mptr = malloc(bytes + sizeof(MEMCHAIN) + 2);
  33.     if (!mptr)
  34.         d__fatal("malloc() failed", bytes, module, line);
  35.     d__add_to_ll(mptr, bytes, module, line);
  36.     return (mptr + 1);
  37. }
  38.  
  39. void *d__calloc(size_t n, size_t bytes, char *module, 
  40.                 int line)
  41. {
  42.     PMEMCHAIN mptr;
  43.  
  44.     if (bytes < 1)
  45.         d__fatal("Called calloc() with < 1 bytes:", 
  46.                     bytes, module, line);
  47.     if (n < 1)
  48.         d__fatal("Called calloc() with count < 1:", 
  49.                     n, module, line);
  50.     mptr = calloc(1, n * bytes + sizeof(MEMCHAIN) + 2);
  51.     if (!mptr)
  52.         d__fatal("calloc() failed", bytes, module, line);
  53.     d__add_to_ll(mptr, n * bytes, module, line);
  54.     return (mptr + 1);
  55. }
  56.  
  57. void *d__realloc(void *rptr, size_t bytes, char *module, 
  58.                  int line)
  59. {
  60.     PMEMCHAIN mptr;
  61.  
  62.     if (!rptr)
  63.         d__fatal("Called realloc() with null pointer", 0, 
  64.                     module, line);
  65.     if (bytes < 1)
  66.         d__fatal("Called realloc() with < 1 bytes:", 
  67.                     bytes, module, line);
  68.     for (mptr = memchainhead; mptr; mptr = mptr->next)
  69.         if (mptr + 1 == (PMEMCHAIN) rptr)
  70.             break;
  71.     if (!mptr)
  72.         d__fatal("Reallocating unallocated memory at", 
  73.                     (int)rptr, module, line);
  74.     if (mptr->sentinal != SENTINAL_INT)
  75.         d__fatal("realloc(): Beginning sentinal damaged--contains",
  76.             mptr->sentinal, module, line);
  77.     if (*(int*)((char *)(mptr + 1) + mptr->bytes) != 
  78.                     SENTINAL_INT)
  79.         d__fatal("Realloc(): Ending sentinal damaged--contains",
  80.             *(int *)((char *)(mptr + 1) + mptr->bytes), 
  81.             module, line);
  82.     mptr = realloc(mptr, bytes + sizeof(MEMCHAIN) + 2);
  83.     if (!mptr)
  84.         d__fatal("realloc() failed", bytes, module, line);
  85.     if (mptr->prev)
  86.         /* Update addresses in linked list */
  87.         mptr->prev->next = mptr;       
  88.     if (mptr->next)
  89.         mptr->next->prev = mptr;
  90.     mptr->bytes = bytes;
  91.     *(int *)((char *)(mptr + 1) + bytes) = SENTINAL_INT;
  92.     return(mptr + 1);              
  93.     /* User address starts after structure */
  94. }
  95. void d__free(void *fptr, char *module, int line)
  96. {
  97.     PMEMCHAIN mptr;
  98.  
  99.     if (!fptr)
  100.         d__fatal("Freeing null pointer", 0, module, line);
  101.     for (mptr = memchainhead; mptr; mptr = mptr->next)
  102.         if (mptr + 1 == (PMEMCHAIN) fptr)
  103.             break;
  104.     if (!mptr)
  105.         d__fatal("Freeing unallocated memory at", 
  106.                  (int)fptr, module, line);
  107.     if (mptr->sentinal != SENTINAL_INT)
  108.         d__fatal("free(): Beginning sentinal damaged--contains",
  109.             mptr->sentinal, module, line);
  110.     if (*(int*)((char *)fptr + mptr->bytes) != SENTINAL_INT)
  111.         d__fatal("free(): Ending sentinal damaged--contains",
  112.             *(int *)((char *)fptr + mptr->bytes), 
  113.             module, line);
  114.     if (mptr->prev)
  115.         /* Drop this entry from list */
  116.         mptr->prev->next = mptr->next;      
  117.     else
  118.         memchainhead = mptr->next;
  119.     if (mptr->next)
  120.         mptr->next->prev = mptr->prev;
  121.     free(mptr);
  122. }
  123.  
  124. void d__add_to_ll(PMEMCHAIN mptr, size_t bytes, char *module, 
  125.                 int line)
  126. {
  127.     void *vptr;
  128.     unsigned short ix;
  129.     char *sptr;
  130.  
  131.     /* First byte past MEMCHAIN structure */
  132.     vptr = mptr + 1;  
  133.     mptr->line = line;
  134.     if (sptr = strrchr(module, '\\'))
  135.         /* Skip path information */
  136.         module = sptr + 1;       
  137.     for (ix = 0; ix < MAXMODS && *modlist[ix] && 
  138.                 strcmp(modlist[ix], module); ix++)
  139.         ;
  140.     if (ix == MAXMODS + 1)
  141.         d__fatal("Module table overflow, MAXMODS =", 
  142.                 MAXMODS, module, line);
  143.     if (!*modlist[ix])
  144.         strcpy(modlist[ix], module);
  145.     mptr->module_ix = ix;
  146.     /* Number of user-requested bytes   */
  147.     mptr->bytes = bytes;            
  148.     mptr->next = memchainhead;     /* Zero if first entry */
  149.     if (memchainhead)               
  150.         /* Place new entry at front of list */
  151.         memchainhead->prev = mptr;
  152.     mptr->prev = 0;
  153.     memchainhead = mptr;
  154.     *(int *)((char *)vptr + bytes) = SENTINAL_INT;
  155.     mptr->sentinal = SENTINAL_INT;
  156. }
  157.  
  158. void d__fatal(char *msg, int value, char *module, int line)
  159. {
  160.     printf("FATAL MEMORY ERROR IN %s LINE %d.\n%s %d\n",
  161.             module, line, msg, value);
  162.     exit(1);
  163. }
  164. void d__showmem()
  165. {
  166.     PMEMCHAIN mptr;
  167.  
  168.     printf("\n****MEMORY DEBUG DISPLAY****\n");
  169.     if (!memchainhead)
  170.         printf("****NO MEMORY ALLOCATED***\n");
  171.     else {
  172.         printf("FILE       LINE SIZE ADDRESS\n");
  173.         for (mptr = memchainhead; mptr; mptr = mptr->next) {
  174.             printf("%-10.10s %.4d %.4d %d\n", 
  175.                     modlist[mptr->module_ix],
  176.                     mptr->line, mptr->bytes, mptr+1);
  177.             if (*(int *)((char *)(mptr + 1) + mptr->bytes) != 
  178.                     SENTINAL_INT)
  179.                 printf("\t***ENDING SENTINAL DAMAGED\n");
  180.             if (mptr->sentinal != SENTINAL_INT)
  181.                 printf("\t***BEGINNING SENTINAL DAMAGED\n");
  182.         }
  183.     }
  184. }
  185.